
package com.vertx.demo;

import io.vertx.codegen.annotations.DataObject;
import io.vertx.core.json.JsonObject;

import java.util.concurrent.atomic.AtomicInteger;

/**
 *
 * Todo.class 实体对象由序号id、标题title、次序order、地址url以及代表待办事项是否完成的一个标识complete组成。
 * 我们可以把它看作是一个简单的Java Bean。它可以被编码成JSON格式的数据，我们在后边会大量使用JSON（事实上，在Vert.x中JSON非常普遍）。
 * 同时注意到我们给Todo类加上了一个注解：@DataObject，这是用于生成JSON转换类的注解。
 *
 * @DataObject 注解被 @DataObject 注解的实体类需要满足以下条件：拥有一个拷贝构造函数以及一个接受一个 JsonObject 对象的构造函数。
 *
 * @author ssk www.8win.com Inc.All rights reserved
 * @version v1.0
 * @date 2019-01-24-上午 10:07
 */
@DataObject(generateConverter = true)
public class Todo {
    // counter
    private static final AtomicInteger acc = new AtomicInteger(0);

    private int id;

    private String title;

    private Boolean completed;

    private Integer order;

    private String url;

    public Todo() {

    }

    public Todo(Todo other) {

        this.id = other.id;
        this.title = other.title;
        this.completed = other.completed;
        this.order = other.order;
        this.url = other.url;
    }

    public Todo(JsonObject obj) {
        // 还未生成Converter的时候需要先注释掉，生成过后再取消注释
        TodoConverter.fromJson(obj, this);
    }

    public Todo(String jsonStr) {

        TodoConverter.fromJson(new JsonObject(jsonStr), this);
    }

    public Todo(int id, String title, Boolean completed, Integer order, String url) {

        this.id = id;
        this.title = title;
        this.completed = completed;
        this.order = order;
        this.url = url;
    }

    public JsonObject toJson() {

        JsonObject json = new JsonObject();
        TodoConverter.toJson(this, json);
        return json;
    }

    public int getId() {

        return id;
    }

    public void setId(int id) {

        this.id = id;
    }

    public void setIncId() {

        this.id = acc.incrementAndGet();
    }

    public static int getIncId() {

        return acc.get();
    }

    public static void setIncIdWith(int n) {

        acc.set(n);
    }

    public String getTitle() {

        return title;
    }

    public void setTitle(String title) {

        this.title = title;
    }

    public Boolean isCompleted() {

        return getOrElse(completed, false);
    }

    public void setCompleted(Boolean completed) {

        this.completed = completed;
    }

    public Integer getOrder() {

        return getOrElse(order, 0);
    }

    public void setOrder(Integer order) {

        this.order = order;
    }

    public String getUrl() {

        return url;
    }

    public void setUrl(String url) {

        this.url = url;
    }

    @Override
    public boolean equals(Object o) {

        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Todo todo = (Todo) o;
        if (id != todo.id) return false;
        if (!title.equals(todo.title)) return false;
        if (completed != null ? !completed.equals(todo.completed) : todo.completed != null) return false;
        return order != null ? order.equals(todo.order) : todo.order == null;
    }

    @Override
    public int hashCode() {

        int result = id;
        result = 31 * result + title.hashCode();
        result = 31 * result + (completed != null ? completed.hashCode() : 0);
        result = 31 * result + (order != null ? order.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {

        return "Todo -> {" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", completed=" + completed +
                ", order=" + order +
                ", url='" + url + '\'' +
                '}';
    }

    private <T> T getOrElse(T value, T defaultValue) {

        return value == null ? defaultValue : value;
    }

    public Todo merge(Todo todo) {

        return new Todo(id,
                getOrElse(todo.title, title),
                getOrElse(todo.completed, completed),
                getOrElse(todo.order, order),
                url);
    }
}
